package com.swing_pinea.render;

import com.swing_pinea.event.PineaEvent;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import static com.swing_pinea.core.Pinea.PINEA_EVENT_QUIT;

public class GameWindow {

    private String title;
    private int width;
    private int height;
    private JFrame frame;
    private BgPanel bgPanel;
    private GamePanel gamePanel;
    private UIPanel uiPanel;

    private final Queue<PineaEvent> eventQueue;
    private static GameWindow instance;

    public GameWindow(String title, int width, int height) {
        this.title = title;
        this.width = width;
        this.height = height;

        frame = new JFrame(title);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                // 退出程序事件
                eventQueue.offer(new PineaEvent(PINEA_EVENT_QUIT, 0));
            }
        });

        JLayeredPane layeredPane = new JLayeredPane();
        layeredPane.setPreferredSize(new Dimension(width, height));

        bgPanel = new BgPanel();
        bgPanel.setBounds(0, 0, width, height);
        layeredPane.add(bgPanel, JLayeredPane.DEFAULT_LAYER);
        
        gamePanel = new GamePanel();
        gamePanel.setBounds(0, 0, width, height);
        layeredPane.add(gamePanel, JLayeredPane.PALETTE_LAYER);

        uiPanel = new UIPanel();
        uiPanel.setBounds(0, 0, width, height);
        layeredPane.add(uiPanel, JLayeredPane.MODAL_LAYER);

        frame.add(layeredPane);
        frame.pack();

        frame.setLocationRelativeTo(null);
        
        eventQueue = new ConcurrentLinkedQueue<>();
        instance = this;
    }

    public void show() {
        frame.setVisible(true);
        
        gamePanel.setFocusable(true);
        SwingUtilities.invokeLater(() -> {
            gamePanel.requestFocusInWindow();
        });
    }

    public void quit() {
        frame.dispose();
        System.exit(0);
    }

    public Queue<PineaEvent> getEventQueue() {
        return eventQueue;
    }

    public GamePanel getGamePanel() {
        return gamePanel;
    }

    public BgPanel getBgPanel() {
        return bgPanel;
    }

    public static GameWindow getInstance() {
        return instance;
    }
}